#ifdef BSP_USING_ON_CHIP_FLASH
#include "drv_flash.h"

#if defined (PKG_USING_FAL)
#include "fal.h"
#endif

#define LOG_TAG    "drv.flash"
#include <drv_log.h>

#if defined(PKG_USING_FAL)

static int fal_flash_read(long offset, rt_uint8_t * buf, size_t size);
static int fal_flash_write(long offset, const rt_uint8_t *buf,size_t size);
static int fal_flash_erase(long offset,size_t size);

const struct fal_flash_dev gd32_onchip_flash = {"onchip_flash", GD32_FLASH_START_ADDRESS, GD32_FLASH_SIZE, SIZE_4KB,{NULL,fal_flash_read,fal_flash_write,fal_flash_erase}};

static int fal_flash_read(long offset, rt_uint8_t * buf, size_t size)
{
     return fmc_read_8bit_data(gd32_onchip_flash.addr+offset,size,(int8_t *)buf);
}
static int fal_flash_write(long offset, const rt_uint8_t *buf,size_t size)
{
     return fmc_write_8bit_data(gd32_onchip_flash.addr+offset,size,(int8_t *)buf);
}
static int fal_flash_erase(long offset,size_t size)
{
     uint32_t first_page = 0,last_pages = 0;
	
	  if((gd32_onchip_flash.addr+offset+size)>GD32_FLASH_END_ADDRESS)
		{
			LOG_E("ERROR: erase outrange flash size ! addr is(0x%p)\n",void(*)(gd32_onchip_flash.addr +offset+size));
			return -RT_EINVAL;
		}
		
		fmc_unlock();
		
	/* clear pending flags */
		fmc_flag_clear(FMC_FLAG_END | FMC_FLAG_OPERR | FMC_FLAG_WPERR | FMC_FLAG_PGMERR | FMC_FLAG_PGSERR);
		
		/*Get the 1st page to erase */
		first_page =get_page(gd32_onchip_flash.addr + offset);
		
		last_pages = get_page(gd32_onchip_flash.addr + offset + size -1) +1;
		
		for(uint32_t i = first_page; i < last_pages; i++)
		{
		   if(FMC_READY  != fmc_page_erase(i))
			 {
			    while(1);
			 }
		}
		
		fmc_lock();
		
		return size;
}


#endif

#endif

